package com.aerospace.serviceprovider.io_nio;


import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.channels.CompletionHandler;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

public class IoNioFileChannel {

    //使用BIO实现文件的读取和写入



//    Java BIO
//    BIO 全称Block-IO 是一种同步且阻塞的通信模式。是一个比较传统的通信方式，模式简单，使用方便。但并发处理能力低，通信耗时，依赖网速。
//
//    Java NIO
//    Java NIO，全程 Non-Block IO ，是Java SE 1.4版以后，针对网络传输效能优化的新功能。是一种非阻塞同步的通信模式。
//
//    NIO 与原来的 I/O 有同样的作用和目的, 他们之间最重要的区别是数据打包和传输的方式。原来的 I/O 以流的方式处理数据，而 NIO 以块的方式处理数据。
//
//    面向流的 I/O 系统一次一个字节地处理数据。一个输入流产生一个字节的数据，一个输出流消费一个字节的数据。
//
//    面向块的 I/O 系统以块的形式处理数据。每一个操作都在一步中产生或者消费一个数据块。按块处理数据比按(流式的)字节处理数据要快得多。但是面向块的 I/O 缺少一些面向流的 I/O 所具有的优雅性和简单性。
//
//    Java AIO
//    Java AIO，全程 Asynchronous IO，是异步非阻塞的IO。是一种非阻塞异步的通信模式。
//
//    在NIO的基础上引入了新的异步通道的概念，并提供了异步文件通道和异步套接字通道的实现。



    //write object to File
    public static void wBio(){
//        ObjectOutputStream oos = null;
//        try {
//            oos = new ObjectOutputStream(new FileOutputStream("testFile"));
//            oos.close();
//        } catch (IOException ex) {
//            ex.printStackTrace();
//        }finally {
//            IOUtils.closeQuietly(oos);
//        }
        try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("tempFile"))){

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

        }
    }

    //Read obj from File
    public static void rBIO(){
        File file = new File("tempFile");
        ObjectInputStream ois = null;
        try{
            ois = new ObjectInputStream(new FileInputStream(file));
            String result = (String) ois.readObject();
            System.out.println(result);
        } catch (IOException e){
            e.printStackTrace();
        } catch (ClassNotFoundException e){
            e.printStackTrace();
        }
    }

    public static void rNIO(){
        String path = "D:\\tempFile.txt";
        FileInputStream fin = null;
        try {
            fin = new FileInputStream(new File(path));
            FileChannel channel = fin.getChannel();
            int capcity = 100; //一次读取字节数
            ByteBuffer bf = ByteBuffer.allocate(capcity);
            int length = -1;
            while ((length = channel.read(bf)) != -1) {
                bf.clear();
                byte[] bytes = bf.array();
                System.out.write(bytes, 0, length);
                System.out.println();
            }
            channel.close();
        }catch (FileNotFoundException e){
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            if (fin != null){
                try{
                    fin.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
    }

    public static void wNIO(){
        String fileName = "out.txt";
        FileOutputStream fos = null;
        try{
            fos = new FileOutputStream(new File(fileName));
            FileChannel channel = fos.getChannel();
            ByteBuffer src = Charset.forName("utf-8").encode("你好你好");
            int length = 0;
            while ((length = channel.write(src)) != 0){
                System.out.println("写入长度" + length);
            }
        }catch (FileNotFoundException e){
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            if(fos != null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void rAIO(){
        Path file = Paths.get("tempFile.txt");
        try {
            AsynchronousFileChannel channel = AsynchronousFileChannel.open(file);
            ByteBuffer buffer = ByteBuffer.allocate(100_00);
            Future<Integer> result = channel.read(buffer, 0);
            while (!result.isDone()){
                System.out.println("看会电视去");
            }
            Integer bytesRead = result.get();
            System.out.println("Bytes read [" + bytesRead + "]");
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

    public static void wAIO(){
        try {
            AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(Paths.get("tempFile.txt"), StandardOpenOption.READ,StandardOpenOption.WRITE,StandardOpenOption.CREATE);
            CompletionHandler<Integer, Object> handler = new CompletionHandler<Integer, Object>() {
                @Override
                public void completed(Integer result, Object attachment) {
                    System.out.println("Attachment: " + attachment + "" + result + "bytes written");
                    System.out.println("CompletionHandler Thread ID:" + Thread.currentThread().getId());
                }

                @Override
                public void failed(Throwable exc, Object attachment) {
                    System.err.println("Attachment:" + attachment + "failed with");
                    exc.printStackTrace();
                }
            };

            System.out.println("Main Thread ID:" + Thread.currentThread().getId());
            fileChannel.write(ByteBuffer.wrap("Sample".getBytes()), 0, "First Write", handler);
            fileChannel.write(ByteBuffer.wrap("box".getBytes()), 0, "Second Write", handler);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
